activity.java的attach()方法,这个方法传入多个参数,有Context,ActivityThread
,Instrumentation等等,我们先不管他们,我们直接找到mWindow = PolicyManager.makeNewWindow(this);
这一行代码,也就意味着我们需要找PolicyManager.java,这时我们需要找的是policy这个类,而不是Ipoliy
,因为Ipolicy是一个接口,这时看到的是new PhoneWindow(context);也就是说attach()方法是得到一个phonewindow对象,
那么这个对象是怎么得到的呢?
我们继续跟踪,去看PhoneWindow.java
看这个类的构造函数,需要调用父类的构造函数,而父类是window,我们看一下,发现mContext = context;
于是我们回到phonewindow.java中,看到mLayoutInflater = LayoutInflater.from(context);我们进入到
LayoutInflater.java中,这是一个抽象类,我们找到from()方法,这个方法类似于得到
一个系统服务,并且得到LayoutInflater类型的变量,如果LayoutInflate这个类型的
变量为空,就会抛出错误LayoutInflate not found.。
然后返回LayoutInflate类型的变量,
也就是说phonewindow的得到其实就是根据Context得到一个系统服务而已,然后我们回
到activity.java中,我们去看setContentView()方法,我们可以看到它调用的是window
的setContentView()方法,我们进入看一下,会发现其实就是说根据你传入的值来设置
view的样子,有两种参数,一种是int layoutResID,还有一种是View view, ViewGroup.LayoutParams params,
这两种参数都行。第一种就会调用LayoutInflater中的inflate(),这个方法至少传入两个参数,如果viewgroup类型的
参数为null,就会返回一个view对象,如果不是null,就会调用viewGroup的addview()方法,而第二个就会直接调用
ViewGroup的addView()方法。也就是说我们可以直接使用以下一些代码来替代eclipse给我们的
setContentView(R.layout.activity_main);
比如: LayoutInflater LayoutInflater1 =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
getWindow().setContentView(LayoutInflater1.inflate(R.layout.activity_main, null));
或者:
LayoutInflater LayoutInflater1 =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
getWindow().setContentView(LayoutInflater1.inflate(R.layout.activity_main, null),new ViewGroup.LayoutParams(-1, -1));

这一种与上一种类似,不过我们就是使用了传入两个参数的setContentView(view arg0,layoutparas arg1)的方法,这里就需要提一下后面的这个参数,
在phoneWindow.java的传入一个参数的setconteneView()方法的源码中是这样的setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
这里的MATCH_PARENT其实是viewgroup的public static int类型的变量,值是-1,之所以这里能直接使用是因为在phoneWindow.java类中导入了,我也是后面反应过来的,语句是
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;这是java的基础知识,就不解释了。
或者:
getWindow().setContentView(LayoutInflater.from(getBaseContext()).inflate(R.layout.init, null),new ViewGroup.LayoutParams(-1, -1));
当然还有很多种搭配方式,这里就不一一赘述了。
总之,LayoutInflater中的inflate()方法的作用是返回一个不为空的view对象,或者是调用addview()方法并返回传入的viewGroup参数,这个根据你传入的ViewGroup类型的变量是否为空,
若为空就返回一个不为空的view对象,若不为空就调用addview方法并返回传入的viewGroup参数,也就是说如果我们能提供一个不为空的viewgroup类型的参数,那么我们就可以直接使用inflate()方法来设置view
(但是我提供了一个不为null的viewgroup对象,,下面是我的代码
Button b=new Button(this);
b.setText(“b”);
LinearLayout linearLayout=new LinearLayout(this);
linearLayout.addView(b);
linearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_main, linearLayout);但是布局是一片空白,我也不知道为什么?),
类似于 LayoutInflater.from(this).inflate(R.layout.activity_main,new AbsoluteLayout(this,null,R.id.myButton) );
但是我并不知道如何构造一个不为空的viewgroup对象,然后
我们利用返回的view对象当参数传入phoneWindow.java中的setContentView(View view);方法中,然后这个方法调用addview()方法来设置view,至于后面那个可有可无的参数,若不传入,
则是宽度高度都是match_parent,也就是为-1,若传入自己设置值,只有-1,-2两个选项有意义,但是我把-1变为-2好像没影响,这个参数应该是控制这个view的宽度和高度呀,但是为什
么没影响。。。
一个activity构造的时候一定会构造一个phonewindow对象,并且只有一个,activity是控制单元,window是承载单元,view是显示视图,打个比方就是,activity是工匠,他做了一个窗户,
而窗户需要贴窗花才好看,layout的那个xml文件就是剪窗花,剪完窗花需要贴上去,而addView就是将窗花贴到窗户上去。

不过这里有一点搞不太明白,就是得到一个LayoutInflater的引用时,由于这个方法是一个抽象方法,也就是意味着不能直接new,
我们可以使用两种方式,一种是使用这个LayoutInflater类中的静态方法from(),还有一种就是
LayoutInflater LayoutInflater =
(LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
(其实这就是from()方法中的主要代码),可是怎么实现的呢?通过对源码的跟踪我发现当你使用from这个方法时,
你会发现当你传入不同的context参数,显示的效果会不同,对于一个button控件而言,用这个参数会是浅黑色的,用getbasecontext是白色的,但是不管你用什么参数,最后应该都会到contextthemewrapper.java中,
而这里的代码是这样的:
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
}
return mInflater;
}
return getBaseContext().getSystemService(name);
这里我就蒙圈了,也就是说它会回到from方法中,可是也没有看到有构造这个对象呀,回到from的话不就又开始周而复始的调用吗?